{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "45b3bc29-dc25-4bc8-a865-5cc537430b78",
   "metadata": {},
   "source": [
    "# Monte Carlo Simulation"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0bfc0241-b312-45cd-b1b6-cfecab9ad85e",
   "metadata": {},
   "source": [
    "# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0d0d0add-ff03-4c37-af3c-3942c8adc582",
   "metadata": {
    "tags": []
   },
   "source": [
    "## Load the Libs we need"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "4b0d19b3-7892-470c-8051-b3460605ed1a",
   "metadata": {},
   "outputs": [],
   "source": [
    "# import Lib\n",
    "import pandas as pd\n",
    "import datetime as dt\n",
    "import pytz\n",
    "import os\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import yfinance as yf\n",
    "import numpy as np\n",
    "import scipy.stats as si\n",
    "import math\n",
    "import networkx as nx\n",
    "\n",
    "# import module\n",
    "from datetime import datetime, timezone\n",
    "from datetime import date, time\n",
    "from math import trunc\n",
    "from dateutil.parser import parse"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fd052078-492b-4796-b81d-63b3d8b747ce",
   "metadata": {},
   "source": [
    "## A simple Pi Example"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "18b49bce-186c-46eb-841c-654624c9b74f",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The function took 6.862377405166626 seconds to run.\n",
      "3.1417184\n"
     ]
    }
   ],
   "source": [
    "import random\n",
    "import math\n",
    "import time\n",
    "\n",
    "def mb_estimate_pi(n):\n",
    "    start_time = time.time()\n",
    "\n",
    "    points_inside_circle = 0\n",
    "    total_points = 0\n",
    "\n",
    "    for _ in range(n):\n",
    "        x = random.uniform(0, 1)\n",
    "        y = random.uniform(0, 1)\n",
    "        distance = math.sqrt(x**2 + y**2)\n",
    "\n",
    "        if distance <= 1:\n",
    "            points_inside_circle += 1\n",
    "        total_points += 1\n",
    "\n",
    "    pi_estimate = 4 * points_inside_circle / total_points\n",
    "    \n",
    "    end_time = time.time()\n",
    "    execution_time = end_time - start_time\n",
    "\n",
    "    print(f\"The function took {execution_time} seconds to run.\")\n",
    "\n",
    "    return pi_estimate\n",
    "\n",
    "# Estimate pi with 1 million points\n",
    "print(mb_estimate_pi(10000000))\n"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "0efaa123-5c85-4c3c-8772-3ffbe77418be",
   "metadata": {},
   "source": [
    "## Pricing an European Option with MCS"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "b3797e3a-401b-4189-98cd-33b4ef55927a",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "European Call Option Value 7.973\n",
      "European Put Option Value 7.898\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "\n",
    "def mb_monte_carlo_option_pricing(S0=100, K=105, T=1.0, r=0.05, sigma=0.2, M=1000, I=50000):\n",
    "    \"\"\"\n",
    "    Parameters:\n",
    "    S0 (float): initial stock price\n",
    "    K (float): strike price\n",
    "    T (float): time-to-maturity\n",
    "    r (float): risk-free rate\n",
    "    sigma (float): volatility\n",
    "    M (int): number of time steps\n",
    "    I (int): number of simulation paths\n",
    "\n",
    "    Returns:\n",
    "    C0 (float): European Call Option Value\n",
    "    P0 (float): European Put Option Value\n",
    "    \"\"\"\n",
    "\n",
    "    # Simulating I paths with M time steps\n",
    "    np.random.seed(1000)\n",
    "    dt = T / M \n",
    "    S = np.zeros((M + 1, I))\n",
    "    S[0] = S0\n",
    "\n",
    "    for t in range(1, M + 1):\n",
    "        z = np.random.standard_normal(I)  \n",
    "        S[t] = S[t - 1] * np.exp((r - 0.5 * sigma ** 2) * dt + sigma * np.sqrt(dt) * z)\n",
    "\n",
    "    # Calculating the Monte Carlo estimator for a European call option\n",
    "    C0 = np.exp(-r * T) * np.sum(np.maximum(S[-1] - K, 0)) / I\n",
    "\n",
    "    # Calculating the Monte Carlo estimator for a European put option\n",
    "    P0 = np.exp(-r * T) * np.sum(np.maximum(K - S[-1], 0)) / I\n",
    "\n",
    "    return C0, P0\n",
    "\n",
    "# Call the function\n",
    "C0, P0 = mb_monte_carlo_option_pricing()\n",
    "print(\"European Call Option Value %5.3f\" % C0)\n",
    "print(\"European Put Option Value %5.3f\" % P0)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "b9790b00-4358-4508-b6e3-e138bde1646c",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.9.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
